function countComponents (n, edges) {
  let uf = new UnionFind(n) // 形成一个并查集
  for (let edge of edges) {
    let from = edge[0]
    let to = edge[1]
    uf.union(from, to)
  }
  return uf.getCount()
}
class UnionFind {
  constructor(n) {
    this.count = n
    this.parent = new Array(n)
    for (let i = 0; i < n; i++) {
      this.parent[i] = i
    }
  }
  union (p, q) {
    let rootP = this.find(p)
    let rootQ = this.find(q)
    if (rootQ === rootP) return
    this.parent[rootQ] = rootP
    this.count--
  }
  connected (p, q) {
    let rootP = this.find(p)
    let rootQ = this.find(q)
    return rootP === rootQ
  }
  find (x) {
    if (this.parent[x] !== x) {
      this.parent[x] = this.find(this.parent[x])
    }
    return this.parent[x]
  }
  getCount () {
    return this.count
  }
}
let n = 5, edges = [[0, 1], [1, 2], [2, 3], [3, 4]]
console.log(countComponents(n, edges))